const { defineConfig } = require("@vue/cli-service");

const path = require("path");

// 引入插件，并生成实例
const { GitRevisionPlugin } = require("git-revision-webpack-plugin");
const gitRevisionPlugin = new GitRevisionPlugin();

// 路径处理方法
function resolve(dir) {
  return path.join(__dirname, dir);
}

//获取到git_commit_id
const child_process = require("child_process");
const commitHash = child_process
  .execSync("git rev-parse --short HEAD")
  .toString()
  .trim();

const packageJson = require("./package.json");

//运行后后添加 version 到 public/version.txt
child_process.execSync(
  `echo ${packageJson.version}-${commitHash} > public/version.txt`
);

const externals = [
  {
    vue: "Vue", // Vue.js
  },
  {
    "vue-router": "VueRouter", // Vue Router
  },
  {
    axios: "axios", // Axios
  },
  {
    md5: "MD5", // MD5
  },
  {
    qs: "Qs", // Qs
  },
];

// 使用外链进行加载 减少包体积大小 和服务器压力 当然这种情况只用在 生产环境
const cdn = {
  css: [], // CSS
  js: [
    "https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js", // Vue.js
    "https://cdn.jsdelivr.net/npm/vue-router@3.5.1/dist/vue-router.min.js", // Vue Router
    "https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js", // Axios
    "https://cdn.jsdelivr.net/npm/md5@2.3.0/dist/md5.min.js", // MD5
    "https://cdn.jsdelivr.net/npm/qs@6.11.0/dist/qs.min.js", // Qs
  ],
};

module.exports = defineConfig({
  publicPath: process.env.NODE_ENV === "production" ? "/" : "/", // publicPath
  outputDir: "dist", // outputDir
  productionSourceMap: false, // productionSourceMap
  lintOnSave: process.env.NODE_ENV !== "production", // lintOnSave
  devServer: {
    port: 8080, // 端口号
    hot: true, // 热更新
    compress: true, // 是否启动压缩 gzip
    proxy: {
      "/api": {
        target: "http://www.xxxx.com", // 代理地址
        changeOrigin: true, // 是否跨域
        pathRewrite: {
          "^/api": "", // 重写路径
        },
      },
    },
  },
  css: {
    loaderOptions: {
      scss: {
        // additionalData: '@import "@/assets/scss/variables.scss";', // 引入全局变量
      },
    },
  },
  // webpack 配置
  configureWebpack: {
    resolve: {
      extensions: [".vue", ".js", ".json", "scss", "css"], // 解析扩展名
      alias: {
        "@": resolve("src"), // 别名
      },
      modules: [resolve("src"), "node_modules"], // 模块路径
    },
    module: {},
    plugins: [],
  },
  // 链接 webpack 配置
  chainWebpack: (config) => {
    // webpack 启动时将 git 信息存储到环境变量中 例子： process.env.COMMIT_HASH
    config.plugin("define").tap((args) => {
      args[0]["process.env"].COMMIT_HASH = JSON.stringify(
        gitRevisionPlugin.commithash()
      );
      args[0]["process.env"].BRANCH = JSON.stringify(
        gitRevisionPlugin.branch()
      );
      args[0]["process.env"].LAST_COMMIT_DATETIME = JSON.stringify(
        new Date().toLocaleDateString()
      );
      return args;
    });

    // 只有在生产模式时才调用
    if (process.env.NODE_ENV === "production") {
      config.externals(externals); // 外部扩展
      // 通过 html-webpack-plugin 将 cdn 注入到 index.html 之中
      config.plugin("html").tap((args) => {
        args[0].cdn = cdn; // 注入cdn
        return args;
      });

      config.plugin("CompressionPlugin").use("compression-webpack-plugin", [
        {
          filename: "[path][base].gz", // 压缩文件名
          algorithm: "gzip", // 压缩算法
          test: /\.js$|\.css$|\.html$/, // 压缩文件类型
          threshold: 10240, // 只处理比这个值大的资源。按字节计算
          minRatio: 0.8, // 只有压缩率比这个值小的资源才会被处理
        },
      ]);
      config.optimization.splitChunks({
        cacheGroups: {
          styles: {
            name: "styles", // 样式文件名
            test: /\.(s?css|less|sass)$/, // 样式文件类型
            chunks: "all",
            priority: 10,
          },
          common: {
            name: "chunk-common", // 公共文件名
            chunks: "all",
            minChunks: 2, // 拆分前必须共享模块的最小 chunks 数。
            maxInitialRequests: 5, // 打包后的入口文件加载时，还能同时加载js文件的数量（包括入口文件）
            minSize: 0, // 生成 chunk 的最小体积（≈ 20kb)
            priority: 1, // 优化将优先考虑具有更高 priority（优先级）的缓存组
            reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块，则它将被重用，而不是生成新的模块
          },
          vendors: {
            name: "chunk-vendors", // 第三方库文件名
            test: /[\\/]node_modules[\\/]/, // 第三方库文件路径
            chunks: "all",
            priority: 2,
            reuseExistingChunk: true,
          },
          //lru-cache是项目中的额外插件，提取为一个单独的 chunk。
          lrucache: {
            name: "chunk-lrucache", // lrucache文件名
            test: /[\\/]node_modules[\\/]_?lru-cache(.*)/, // lrucache文件路径
            chunks: "all",
            priority: 3,
          },
        },
      });
    }
  },
});
